package com.yanyeori.framework.web.http.request.feign;

import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import com.yanyeori.framework.web.http.request.feign.context.HeaderConverterContextHolder;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import java.util.Collection;
import java.util.concurrent.Callable;

/**
 * 创建一个自定义的hystrix 线程策略, 将servletRequestAttributes传入新线程中，并赋给RequestContextHolder
 *
 * @author chenkuan
 * @since 2021/7/30
 */
public class MyHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {

    private final FeignRequestInterceptor feignRequestInterceptor;

    public MyHystrixConcurrencyStrategy(FeignRequestInterceptor feignRequestInterceptor) {
        this.feignRequestInterceptor = feignRequestInterceptor;
    }

    @Override
    public <T> Callable<T> wrapCallable(Callable<T> callable) {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        Collection<Object> contexts = feignRequestInterceptor.getContext();
        return () -> {
            try {
                if (requestAttributes != null) {
                    RequestContextHolder.setRequestAttributes(requestAttributes);
                }
                if (CollectionUtils.isNotEmpty(contexts)) {
                    HeaderConverterContextHolder.setHeaderContext(contexts);
                }
                return callable.call();
            } finally {
                RequestContextHolder.resetRequestAttributes();
                HeaderConverterContextHolder.clear();
            }
        };
    }
}